<!-- 
必须在子组件设置相同的组id【groupId】才能使组生效
-->
<template>
	<view class="vi_checkboxGroup" :style="mainStyle">
		<slot></slot>
	</view>
</template>

<script>
	export default {
		name:"viCheckboxGroup",
		model:{
			prop: "value",
			event: "input"
		},
		props:{
			value:{
				type:[Array,String,Number,null],
				default:()=>[]
			},
			disabled:{
				type:[Boolean,null],
				default:false
			},
			readOnly:{
				type:[Boolean,null],
				default:false
			},
			max:{
				type:[Number,null],
				default:0
			},
			groupId:{
				required:true,
				type:[String,null],
				default:""
			},
			isRadio:{
				type:[Boolean,null],
				default:false
			},
			nowrap:{
				type:[Boolean,null],
				default:false
			},
			vertical:{
				type:[Boolean,null],
				default:false
			},
			text:{
				type:[Object,null],
				default:()=>({})
			},
			//方块模式，复选框变成按钮
			buttonMode:{
				type:[Boolean,null],
				default:false
			},
			width:{
				type:[String,null],
				default:""
			},
			height:{
				type:[String,null],
				default:""
			},
			radius:{
				type:[String, Number, null],
				default:null
			}
		},
		data() {
			return {
				inValues:[],
				dicText:{
					tipCheckMaxError: "最多允许选择${max}项",
					tipCheckAllError: "最多允许选择${max}项，请手动勾选"
				},
			}
		},
		computed:{
			mainStyle(){
				let res = "";
				if(!this.nowrap){
					res += "flex-wrap:wrap;"
				}
				if(this.vertical){
					res += "flex-direction:column;"
				}
				return res
			},
			textSetting(){
				if(this.$api.isObject(this.text)){
					return Object.assign({},this.dicText,this.text)
				}
				return this.dicText
			}
		},
		methods: {
			noRepeart(){//简化合并操作，去重复
				this.inValues = [...new Set(this.inValues)];
			},
			emitEvent(){//简化合并操作，提交，radio只返回单值
				if(this.isRadio){
					this.$emit('change', this.inValues[0]);
					this.$emit('input', this.inValues[0]);
				}else{
					this.$emit('change', this.inValues);
					this.$emit('input', this.inValues);
				}
			},
			//返回当前组的disabled，子组件用
			getDisabled(){
				return this.disabled
			},
			getReadOnly(){
				return this.readOnly
			},
			//子组件数据变更，单项
			checkboxChange(value, checked){
				if(!this.$api.isValue(value)){//没有value值不处理
					return false
				}
				if(this.isRadio){
					////检查是否有选中项且不能变更，如果是则不能更改。(目前允许更改)
					// let children = this.getChildren();
					// for(let item of children){
					// 	if(item.inChecked&&(item.inDisabled||item.inReadOnly)){
					// 		return false
					// 	}
					// }
					this.inValues = [value];
				}else{
					if(checked){//添加
						//检查是否超出选择限制，超出则不予更改
						if(this.max && this.inValues.length >= this.max){
							let msg = this.textSetting.tipCheckMaxError.replace("${max}",this.max);
							this.$api.msg(msg, "error")
							return false
						}
						this.inValues.push(value);
						// 进行一次去重
						this.noRepeart();
					}else{//删除
						// 先进行一次去重
						this.noRepeart();
						let idx = this.inValues.indexOf(value);
						this.inValues.splice(idx,1);
					}
				}
				this.setChildren();
				//向外提交事件
				this.emitEvent();
				return true;
			},
			//全选
			selectAll(){
				//单选类型不能全选
				if(this.isRadio){
					return
				}
				let children = this.getChildren();
				//总数大于选择数量限制时不能全选
				if(this.max && children.length >= this.max){
					let msg = this.textSetting.tipCheckAllError.replace("${max}",this.max);
					this.$api.msg(msg, "warning")
					return
				}
				for(let item of children){
					let val = item.setCheck(true);
					if(this.$api.isValue(val) && val!==true){
						this.inValues.push(val);
					}
				}
				//进行一次去重
				this.noRepeart();
				//执行完毕后向外提交事件
				this.emitEvent();
			},
			//全取消
			clearAll(){
				//单选类型不能取消
				if(this.isRadio){
					return
				}
				//先进行一次去重
				this.noRepeart();
				let children = this.getChildren();
				for(let item of children){
					let val = item.setCheck(false);
					if(this.$api.isValue(val) && val!==true){
						let idx = this.inValues.indexOf(val);
						this.inValues.splice(idx,1);
					}
				}
				//执行完毕后触发chuange事件
				this.emitEvent();
			},
			//根据组的值，设置子组件选中。观测到组数据变更时使用强制设置
			setChildren(force=false){
				let children = this.getChildren();
				for(let i=0,len=children.length; i<len; i++){
					let item = children[i];
					let val = item.getValue();
					if(this.isRadio){
						item.setCheck(this.inValues==val? true:false, force);
					}else{
						item.setCheck(this.inValues.includes(val)? true:false, force);
					}
					//设置方块模式
					if(force){
						item.setButtonMode({
							buttonMode: this.buttonMode,
							width: this.width||"",
							height: this.height||"",
							radius: this.radius,
							first: i==0&&len>1&&!this.vertical,
							center: i>0&&i<len-1&&!this.vertical,
							last: i>0&&i==len-1&&!this.vertical
						})
					}
				}
			},
			//获取子组件
			getChildren(){
				if(this.groupId){
					return this.$api.getChildren(this, "viCheckbox", "groupId")
				}
				console.error("checkbox-group未设置groupId");
				return []
			},
		},
		watch:{
			"value": {
				immediate:true,
				handler(newValue) {
					if(this.isRadio){//单选为值
						this.inValues = newValue ||""
					}else{
						if(this.$api.isArray(newValue)){
							this.inValues = newValue
						}else if(this.$api.isValue(newValue)){
							this.inValues = [newValue]
						}else{
							this.inValues = []
						}
					}
					//组挂载以后才能拿到子组件，挂载前this.$children==[]
					this.$nextTick(()=>{
						this.setChildren(true);//组数据被外部变更，强制对子组件赋值，不管其是否disabled
					})
				}
			},
			//组禁用、只读变更需要手动更新子复选框，子复选框不会观测
			"disabled":{
				handler(newValue){
					let children = this.getChildren();
					for(let item of children){
						item.setDisabled()
					}
				}
			},
			"readOnly":{
				handler(newValue){
					let children = this.getChildren();
					for(let item of children){
						item.setDisabled()
					}
				}
			}
		},
	}
</script>

<style lang="scss">
.vi_checkboxGroup{
	display: flex;
	align-items: center;
	flex-wrap: wrap;
}
</style>
